昨日介紹產生遙測資料的基本,以及提到了在同個微服務的情況下怎麼樣讓Span跟Span連接在一起,但是問題是在微服務架構的底下,真正面對的情況是很多種不同的微服務,那應該要怎麼解決這個問題?
這時候就要透過前面在上下文傳播提到的「傳播」,不得不說這也是一個很棒的功能,只是有點小問題...
我們先來講講怎麼做上下文傳播,一樣我們來看文件給的範例程式碼:
from flask import Flask
import requests
from opentelemetry import trace, propagators, baggage
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from opentelemetry.baggage.propagation import W3CBaggagePropagator
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, BatchSpanProcessor
app = Flask(__name__)
trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
tracer = trace.get_tracer(__name__)
@app.route('/')
def hello():
with tracer.start_as_current_span("api1_span") as span:
ctx = baggage.set_baggage("hello", "world")
headers = {}
W3CBaggagePropagator().inject(headers, ctx)
TraceContextTextMapPropagator().inject(headers, ctx)
print(headers)
response = requests.get('http://127.0.0.1:5001/', headers=headers)
return f"Hello from API 1! Response from API 2: {response.text}"
if __name__ == '__main__':
app.run(port=5002)
from flask import Flask, request
from opentelemetry import trace, baggage
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, BatchSpanProcessor
from opentelemetry.baggage.propagation import W3CBaggagePropagator
app = Flask(__name__)
trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
tracer = trace.get_tracer(__name__)
@app.route('/')
def hello():
# Example: Log headers received in the request in API 2
headers = dict(request.headers)
print(f"Received headers: {headers}")
carrier ={'traceparent': headers['Traceparent']}
ctx = TraceContextTextMapPropagator().extract(carrier=carrier)
print(f"Received context: {ctx}")
b2 ={'baggage': headers['Baggage']}
ctx2 = W3CBaggagePropagator().extract(b2, context=ctx)
print(f"Received context2: {ctx2}")
# Start a new span
with tracer.start_span("api2_span", context=ctx2):
# Use propagated context
print(baggage.get_baggage('hello', ctx2))
return "Hello from API 2!"
if __name__ == '__main__':
app.run(port=5001)
提到上下文傳播就不能不提到Baggage,所以從上述的程式碼可以觀察出來,如果想要跨服務將Span串起
首先就是在A微服務將訊息inject到bagage,
ctx = baggage.set_baggage("hello", "world")
headers = {}
W3CBaggagePropagator().inject(headers, ctx)
TraceContextTextMapPropagator().inject(headers, ctx)
response = requests.get('http://127.0.0.1:5001/', headers=headers)
W3CBaggagePropagator().inject(headers, ctx)
:將 baggage 的上下文 inject 到 headers 中。這使得該上下文可以通過 HTTP 請求傳播到其他服務中。TraceContextTextMapPropagator().inject(headers, ctx)
:將 trace 上下文 inject 到 headers 中。這使得 trace ID 和 span ID 等資訊能夠在 HTTP 請求中傳播。
接下來B微服務將訊息extract出來
headers = dict(request.headers)
carrier ={'traceparent': headers['Traceparent']}
ctx = TraceContextTextMapPropagator().extract(carrier=carrier)
carrier = {'traceparent': headers['Traceparent']}
:從接收到的標頭中提取 traceparent,這是 OpenTelemetry 用來傳遞追踪上下文的一個標頭。ctx = TraceContextTextMapPropagator().extract(carrier=carrier)
:使用 TraceContextTextMapPropagator 從 traceparent 中提extract追蹤上下文,並創建一個 OpenTelemetry 的上下文 ctx,這個上下文會包含來自前一個微服務的資料。
今天就是介紹實作上下文傳播的三大重點